import time
import json
from pathlib import Path
import ctypes
import platform
import threading
import os

# 根据操作系统选择合适的库加载方式
if platform.system() == 'Windows':
    import ctypes.wintypes

    user32 = ctypes.WinDLL('user32', use_last_error=True)
    gdi32 = ctypes.WinDLL('gdi32', use_last_error=True)
    imm32 = ctypes.WinDLL('imm32', use_last_error=True)
else:
    # Linux系统不支持Windows API，提供空实现
    class MockWinDLL:
        def __getattr__(self, name):
            def mock_func(*args, **kwargs):
                print(f"Mock {name} called")
                return 0

            return mock_func


    user32 = MockWinDLL()
    gdi32 = MockWinDLL()
    imm32 = MockWinDLL()


    # 定义必要的常量
    class wintypes:
        HWND = ctypes.c_void_p
        HDC = ctypes.c_void_p
        DWORD = ctypes.c_uint32
        COLORREF = ctypes.c_uint32
        SIZE = ctypes.c_int * 2
        POINT = ctypes.c_int * 2
        LPARAM = ctypes.c_long
        WPARAM = ctypes.c_ulonglong


    ctypes.wintypes = wintypes

# 定义常量
HWND_DESKTOP = 0
SRCCOPY = 0x00CC0020
TRANSPARENT = 0x0001  # 透明背景模式
OPAQUE = 0x0002  # 不透明背景模式
RGB_RED = 0x000000FF  # 红色(0x00BBGGRR格式)
RGB_YELLOW = 0x0000FFFF  # 黄色
RGB_GREEN = 0x0000FF00  # 绿色
RGB_BLUE = 0x00FF0000  # 蓝色

# 键盘相关常量
# 字母键
VK_A = 0x41  # A键
VK_B = 0x42  # B键
VK_C = 0x43  # C键
VK_D = 0x44  # D键
VK_E = 0x45  # E键
VK_F = 0x46  # F键
VK_G = 0x47  # G键
VK_H = 0x48  # H键
VK_I = 0x49  # I键
VK_J = 0x4A  # J键
VK_K = 0x4B  # K键
VK_L = 0x4C  # L键
VK_M = 0x4D  # M键
VK_N = 0x4E  # N键
VK_O = 0x4F  # O键
VK_P = 0x50  # P键
VK_Q = 0x51  # Q键
VK_R = 0x52  # R键
VK_S = 0x53  # S键
VK_T = 0x54  # T键
VK_U = 0x55  # U键
VK_V = 0x56  # V键
VK_W = 0x57  # W键
VK_X = 0x58  # X键
VK_Y = 0x59  # Y键
VK_Z = 0x5A  # Z键

# 数字键
VK_0 = 0x30  # 0键
VK_1 = 0x31  # 1键
VK_2 = 0x32  # 2键
VK_3 = 0x33  # 3键
VK_4 = 0x34  # 4键
VK_5 = 0x35  # 5键
VK_6 = 0x36  # 6键
VK_7 = 0x37  # 7键
VK_8 = 0x38  # 8键
VK_9 = 0x39  # 9键

# 功能键
VK_F1 = 0x70  # F1键
VK_F2 = 0x71  # F2键
VK_F3 = 0x72  # F3键
VK_F4 = 0x73  # F4键
VK_F5 = 0x74  # F5键
VK_F6 = 0x75  # F6键
VK_F7 = 0x76  # F7键
VK_F8 = 0x77  # F8键
VK_F9 = 0x78  # F9键
VK_F10 = 0x79  # F10键
VK_F11 = 0x7A  # F11键
VK_F12 = 0x7B  # F12键

# 控制键
VK_CONTROL = 0x11  # Ctrl键
VK_SHIFT = 0x10  # Shift键
VK_ALT = 0x12  # Alt键
VK_CAPITAL = 0x14  # Caps Lock键
VK_ESCAPE = 0x1B  # Esc键
VK_SPACE = 0x20  # 空格键
VK_TAB = 0x09  # Tab键
VK_BACK = 0x08  # Backspace键
VK_RETURN = 0x0D  # Enter键
VK_DELETE = 0x2E  # Delete键

# 方向键
VK_UP = 0x26  # 上箭头键
VK_DOWN = 0x28  # 下箭头键
VK_LEFT = 0x25  # 左箭头键
VK_RIGHT = 0x27  # 右箭头键

# 导航键
VK_HOME = 0x24  # Home键
VK_END = 0x23  # End键
VK_PRIOR = 0x21  # Page Up键
VK_NEXT = 0x22  # Page Down键
VK_INSERT = 0x2D  # Insert键

# 其他键
VK_LWIN = 0x5B  # 左Windows键
VK_RWIN = 0x5C  # 右Windows键
VK_APPS = 0x5D  # 应用程序键
VK_SLEEP = 0x5F  # Sleep键

# 数字小键盘键
VK_NUMPAD0 = 0x60  # 小键盘0
VK_NUMPAD1 = 0x61  # 小键盘1
VK_NUMPAD2 = 0x62  # 小键盘2
VK_NUMPAD3 = 0x63  # 小键盘3
VK_NUMPAD4 = 0x64  # 小键盘4
VK_NUMPAD5 = 0x65  # 小键盘5
VK_NUMPAD6 = 0x66  # 小键盘6
VK_NUMPAD7 = 0x67  # 小键盘7
VK_NUMPAD8 = 0x68  # 小键盘8
VK_NUMPAD9 = 0x69  # 小键盘9
VK_MULTIPLY = 0x6A  # 小键盘*
VK_ADD = 0x6B  # 小键盘+
VK_SEPARATOR = 0x6C  # 小键盘,
VK_SUBTRACT = 0x6D  # 小键盘-
VK_DECIMAL = 0x6E  # 小键盘.
VK_DIVIDE = 0x6F  # 小键盘/

# 键盘事件标志
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP = 0x0002

# 鼠标事件常量
MOUSEEVENTF_RIGHTDOWN = 0x0008  # 鼠标右键按下
MOUSEEVENTF_RIGHTUP = 0x0010  # 鼠标右键释放

# 输入法相关常量
KLF_ACTIVATE = 0x00000001
KLF_SUBSTITUTE_OK = 0x00000002
ENGLISH_LAYOUT_ID = "00000409"  # 英文(美国)键盘布局ID

# 函数原型原型定义
user32.GetDC.argtypes = [ctypes.wintypes.HWND]
user32.GetDC.restype = ctypes.wintypes.HDC

user32.ReleaseDC.argtypes = [ctypes.wintypes.HWND, ctypes.wintypes.HDC]
user32.ReleaseDC.restype = ctypes.c_int

user32.GetSystemMetrics.argtypes = [ctypes.c_int]
user32.GetSystemMetrics.restype = ctypes.c_int

user32.UpdateWindow.argtypes = [ctypes.wintypes.HWND]
user32.UpdateWindow.restype = ctypes.c_bool

user32.GetKeyState.argtypes = [ctypes.c_int]
user32.GetKeyState.restype = ctypes.wintypes.SHORT

user32.keybd_event.argtypes = [ctypes.c_byte, ctypes.c_byte, ctypes.c_ulong, ctypes.c_ulong]
user32.keybd_event.restype = None

user32.mouse_event.argtypes = [ctypes.c_ulong, ctypes.c_long, ctypes.c_long, ctypes.c_long, ctypes.c_ulong]
user32.mouse_event.restype = None

user32.LoadKeyboardLayoutW.argtypes = [ctypes.c_wchar_p, ctypes.c_uint]
user32.LoadKeyboardLayoutW.restype = ctypes.wintypes.HKL

user32.ActivateKeyboardLayout.argtypes = [ctypes.wintypes.HKL, ctypes.c_uint]
user32.ActivateKeyboardLayout.restype = ctypes.wintypes.HKL

user32.GetForegroundWindow.argtypes = []
user32.GetForegroundWindow.restype = ctypes.wintypes.HWND

user32.GetWindowThreadProcessId.argtypes = [ctypes.wintypes.HWND, ctypes.POINTER(ctypes.wintypes.DWORD)]
user32.GetWindowThreadProcessId.restype = ctypes.wintypes.DWORD

imm32.ImmGetContext.argtypes = [ctypes.wintypes.HWND]
imm32.ImmGetContext.restype = ctypes.c_void_p

imm32.ImmSetConversionStatus.argtypes = [ctypes.c_void_p, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD]
imm32.ImmSetConversionStatus.restype = ctypes.c_bool

imm32.ImmReleaseContext.argtypes = [ctypes.wintypes.HWND, ctypes.c_void_p]
imm32.ImmReleaseContext.restype = ctypes.c_bool

gdi32.CreateCompatibleDC.argtypes = [ctypes.wintypes.HDC]
gdi32.CreateCompatibleDC.restype = ctypes.wintypes.HDC

gdi32.CreateCompatibleBitmap.argtypes = [ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int]
gdi32.CreateCompatibleBitmap.restype = ctypes.wintypes.HBITMAP

gdi32.SelectObject.argtypes = [ctypes.wintypes.HDC, ctypes.wintypes.HGDIOBJ]
gdi32.SelectObject.restype = ctypes.wintypes.HGDIOBJ

gdi32.DeleteObject.argtypes = [ctypes.wintypes.HGDIOBJ]
gdi32.DeleteObject.restype = ctypes.c_bool

gdi32.DeleteDC.argtypes = [ctypes.wintypes.HDC]
gdi32.DeleteDC.restype = ctypes.c_bool

gdi32.BitBlt.argtypes = [ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
                         ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int, ctypes.c_uint]
gdi32.BitBlt.restype = ctypes.c_bool

gdi32.CreateFontW.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
                              ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint,
                              ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_wchar_p]
gdi32.CreateFontW.restype = ctypes.wintypes.HFONT

gdi32.TextOutW.argtypes = [ctypes.wintypes.HDC, ctypes.c_int, ctypes.c_int, ctypes.c_wchar_p, ctypes.c_int]
gdi32.TextOutW.restype = ctypes.c_bool

gdi32.SetTextColor.argtypes = [ctypes.wintypes.HDC, ctypes.wintypes.COLORREF]
gdi32.SetTextColor.restype = ctypes.wintypes.COLORREF

gdi32.SetBkMode.argtypes = [ctypes.wintypes.HDC, ctypes.c_int]
gdi32.SetBkMode.restype = ctypes.c_int

gdi32.GetTextExtentPoint32W.argtypes = [ctypes.wintypes.HDC, ctypes.c_wchar_p, ctypes.c_int,
                                        ctypes.POINTER(ctypes.wintypes.SIZE)]
gdi32.GetTextExtentPoint32W.restype = ctypes.c_bool

# 全局变量 - 当前选中的种族
current_race = "人族"
race_lock = threading.Lock()


def switch_to_english_input():
    """切换到英文输入法"""
    try:
        # 方法1：使用LoadKeyboardboardLayout和ActivateKeyboardLayout切换键盘布局
        print("正在正在切换到英文输入法...")

        # 加载英文键盘布局
        hkl = user32.LoadKeyboardLayoutW(ENGLISH_LAYOUT_ID, KLF_ACTIVATE | KLF_SUBSTITUTE_OK)
        if not hkl:
            raise ctypes.WinError(ctypes.get_last_error())

        # 激活英文键盘布局
        result = user32.ActivateKeyboardLayout(hkl, KLF_ACTIVATE)
        if not result:
            raise ctypes.WinError(ctypes.get_last_error())

        # 方法2：额外确保当前窗口的输入法也切换到英文
        hwnd = user32.GetForegroundWindow()
        if hwnd:
            # 获取当前窗口的线程ID
            thread_id = user32.GetWindowThreadProcessId(hwnd, None)

            # 获取输入法上下文
            ime_context = imm32.ImmGetContext(hwnd)
            if ime_context:
                # 设置输入法为英文模式
                imm32.ImmSetConversionStatus(ime_context, 0, 0)
                imm32.ImmReleaseContext(hwnd, ime_context)

        print("已成功切换到英文输入法")
        return True


    except Exception as e:
        print(f"切换输入法失败: {str(e)}")
        # 如果方法1失败，尝试方法3：模拟按下Alt+Shift切换
        try:
            print("尝试使用Alt+Shift快捷键切换输入法...")
            user32.keybd_event(VK_ALT, 0, 0, 0)
            user32.keybd_event(VK_SHIFT, 0, 0, 0)
            time.sleep(0.1)
            user32.keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0)
            user32.keybd_event(VK_ALT, 0, KEYEVENTF_KEYUP, 0)
            print("已发送Alt+Shift快捷键")
            return True
        except Exception as e2:
            print(f"快捷键切换也失败: {str(e2)}")
            return False


def load_time_texts(json_path="time_texts.json"):
    """读取JSON配置文件"""
    if not Path(json_path).exists():
        default_data = {
            "0分:10秒": "别发呆",
            "0分:30秒": "下2矿",
            "1分:00秒": "下3矿",
            "1分:30秒": "起飞"
        }
        with open(json_path, "w", encoding="utf-8") as f:
            json.dump(default_data, f, ensure_ascii=False, indent=2)
        return default_data

    with open(json_path, "r", encoding="utf-8") as f:
        return json.load(f)


def get_current_race():
    """获取当前选中的种族"""
    global current_race
    with race_lock:
        return current_race


def set_current_race(race):
    """设置当前选中的种族"""
    global current_race
    with race_lock:
        current_race = race


def get_race_config(race_name, config_type=None):
    """获取指定种族的配置"""
    config = load_keyboard_config()
    race_section = config.get("种族", {}).get(race_name, {})

    if config_type:
        return race_section.get(config_type, {})
    return race_section


def load_keyboard_config(json_path="keyboard_config.json"):
    """读取键盘配置JSON文件"""
    if not Path(json_path).exists():
        default_data = {
            "global_shortcuts": {
                "start_timing": {
                    "keys": ["ctrl", "f10"],
                    "description": "启动计时和中文提示"
                },
                "exit_program": {
                    "keys": ["ctrl", "shift", "f10"],
                    "description": "退出整个程序"
                }
            },
            "种族": {
                "人族": {
                    "start_auto_key": {
                        "keys": ["ctrl", "f11"],
                        "description": "启动自动按键序列",
                        "auto_key_sequence": {
                            "duration_minutes": 1,
                            "duration_interval_seconds": 3,
                            "actions": [
                                {
                                    "key": "5",
                                    "times": 2,
                                    "interval": 10,
                                    "after_interval": 30
                                },
                                {
                                    "key": "s",
                                    "times": 3,
                                    "interval": 10
                                }
                            ]
                        }
                    },
                    "stop_auto_key": {
                        "keys": ["ctrl", "shift", "f11"],
                        "description": "停止自动按键序列"
                    },
                    "keyboard_shortcuts": [
                        {
                            "trigger_key": "q",
                            "actions": [
                                {"key": "9", "times": 3, "interval": 1000, "after_interval": 10000},
                                {"key": "n", "times": 2, "interval": 1000}
                            ]
                        },
                        {
                            "trigger_key": "w",
                            "actions": [
                                {"key": "0", "times": 1, "interval": 1000}
                            ]
                        }
                    ],
                    "mouse_shortcuts": [
                        {
                            "trigger_event": "left_click",
                            "actions": [
                                {"key": "f5", "times": 1, "interval": 100}
                            ]
                        },
                        {
                            "trigger_event": "right_click",
                            "actions": [
                                {"key": "esc", "times": 1, "interval": 100}
                            ]
                        },
                        {
                            "trigger_event": "wheel_up",
                            "actions": [
                                {"key": "up", "times": 3, "interval": 100}
                            ]
                        },
                        {
                            "trigger_event": "wheel_down",
                            "actions": [
                                {"key": "down", "times": 3, "interval": 100}
                            ]
                        }
                    ]
                },
                "神族": {
                    "start_auto_key": {
                        "keys": ["ctrl", "f11"],
                        "description": "启动自动按键序列",
                        "auto_key_sequence": {
                            "duration_minutes": 1,
                            "duration_interval_seconds": 3,
                            "actions": [
                                {
                                    "key": "6",
                                    "times": 2,
                                    "interval": 10,
                                    "after_interval": 30
                                },
                                {
                                    "key": "d",
                                    "times": 3,
                                    "interval": 10
                                }
                            ]
                        }
                    },
                    "stop_auto_key": {
                        "keys": ["ctrl", "shift", "f11"],
                        "description": "停止神族自动按键序列"
                    },
                    "keyboard_shortcuts": [
                        {
                            "trigger_key": "q",
                            "actions": [
                                {"key": "8", "times": 25, "interval": 10, "after_interval": 10},
                                {"key": "right_click", "times": 1, "interval": 10}
                            ]
                        },
                        {
                            "trigger_key": "w",
                            "actions": [
                                {"key": "1", "times": 15, "interval": 10, "after_interval": 10},
                                {"key": "m", "times": 6, "interval": 10}
                            ]
                        }
                    ],
                    "mouse_shortcuts": [
                        {
                            "trigger_event": "right_click",
                            "actions": [
                                {"key": "space", "times": 1, "interval": 100}
                            ]
                        }
                    ]
                },
                "虫族": {
                    "start_auto_key": {
                        "keys": ["ctrl", "f11"],
                        "description": "启动自动按键序列",
                        "auto_key_sequence": {
                            "duration_minutes": 1,
                            "duration_interval_seconds": 3,
                            "actions": [
                                {
                                    "key": "7",
                                    "times": 2,
                                    "interval": 10,
                                    "after_interval": 30
                                },
                                {
                                    "key": "a",
                                    "times": 3,
                                    "interval": 10
                                }
                            ]
                        }
                    },
                    "stop_auto_key": {
                        "keys": ["ctrl", "shift", "f11"],
                        "description": "停止虫族自动按键序列"
                    },
                    "keyboard_shortcuts": [
                        {
                            "trigger_key": "q",
                            "actions": [
                                {"key": "7", "times": 35, "interval": 10, "after_interval": 10},
                                {"key": "right_click", "times": 1, "interval": 10}
                            ]
                        },
                        {
                            "trigger_key": "w",
                            "actions": [
                                {"key": "2", "times": 25, "interval": 10, "after_interval": 10},
                                {"key": "b", "times": 10, "interval": 10}
                            ]
                        }
                    ],
                    "mouse_shortcuts": [
                        {
                            "trigger_event": "right_click",
                            "actions": [
                                {"key": "tab", "times": 1, "interval": 100}
                            ]
                        }
                    ]
                }
            }
        }
        with open(json_path, "w", encoding="utf-8") as f:
            json.dump(default_data, f, ensure_ascii=False, indent=2)
        return default_data

    with open(json_path, "r", encoding="utf-8") as f:
        config = json.load(f)

        # 确保配置文件结构正确
        if "global_shortcuts" not in config:
            config["global_shortcuts"] = {
                "start_timing": {
                    "keys": ["ctrl", "f10"],
                    "description": "启动计时和中文提示"
                },
                "exit_program": {
                    "keys": ["ctrl", "shift", "f10"],
                    "description": "退出整个程序"
                }
            }

        if "种族" not in config:
            config["种族"] = {}

        # 确保三个种族都存在
        if "人族" not in config["种族"]:
            config["种族"]["人族"] = {
                "start_auto_key": {
                    "keys": ["ctrl", "f11"],
                    "description": "启动自动按键序列",
                    "auto_key_sequence": {
                        "duration_minutes": 1,
                        "duration_interval_seconds": 3,
                        "actions": [
                            {
                                "key": "5",
                                "times": 2,
                                "interval": 10,
                                "after_interval": 30
                            },
                            {
                                "key": "s",
                                "times": 3,
                                "interval": 10
                            }
                        ]
                    }
                },
                "stop_auto_key": {
                    "keys": ["ctrl", "shift", "f11"],
                    "description": "停止自动按键序列"
                },
                "keyboard_shortcuts": [],
                "mouse_shortcuts": []
            }

        if "神族" not in config["种族"]:
            config["种族"]["神族"] = {
                "start_auto_key": {
                    "keys": ["ctrl", "f11"],
                    "description": "启动自动按键序列",
                    "auto_key_sequence": {
                        "duration_minutes": 1,
                        "duration_interval_seconds": 3,
                        "actions": [
                            {
                                "key": "6",
                                "times": 2,
                                "interval": 10,
                                "after_interval": 30
                            },
                            {
                                "key": "d",
                                "times": 3,
                                "interval": 10
                            }
                        ]
                    }
                },
                "stop_auto_key": {
                    "keys": ["ctrl", "shift", "f11"],
                    "description": "停止神族自动按键序列"
                },
                "keyboard_shortcuts": [],
                "mouse_shortcuts": []
            }

        if "虫族" not in config["种族"]:
            config["种族"]["虫族"] = {
                "start_auto_key": {
                    "keys": ["ctrl", "f11"],
                    "description": "启动自动按键序列",
                    "auto_key_sequence": {
                        "duration_minutes": 1,
                        "duration_interval_seconds": 3,
                        "actions": [
                            {
                                "key": "7",
                                "times": 2,
                                "interval": 10,
                                "after_interval": 30
                            },
                            {
                                "key": "a",
                                "times": 3,
                                "interval": 10
                            }
                        ]
                    }
                },
                "stop_auto_key": {
                    "keys": ["ctrl", "shift", "f11"],
                    "description": "停止虫族自动按键序列"
                },
                "keyboard_shortcuts": [],
                "mouse_shortcuts": []
            }

        return config


def get_available_races():
    """获取可用的种族列表"""
    config = load_keyboard_config()
    return list(config.get("种族", {}).keys())


def switch_race(direction):
    """切换种族配置"""
    races = get_available_races()
    if not races:
        print("没有可用的种族配置")
        return

    current = get_current_race()
    current_index = races.index(current) if current in races else 0

    if direction == "next":
        new_index = (current_index + 1) % len(races)
    elif direction == "prev":
        new_index = (current_index - 1) % len(races)
    else:
        return

    new_race = races[new_index]
    set_current_race(new_race)

    # 在桌面显示种族切换提示
    draw_animated_text(f"已切换到{new_race}", size=80, x=500, y=500, color=RGB_GREEN, sleepseconds=0.5)
    print(f"\n已切换到{new_race}配置")

    return new_race


def draw_transparent_text(text, size=100, x=100, y=100, color=RGB_RED, font_name="SimHei"):
    """在内存DC中使用透明背景绘制文字并显示到桌面"""
    try:
        # 获取桌面设备上下文
        hdc_screen = user32.GetDC(HWND_DESKTOP)
        if not hdc_screen:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建内存设备上下文(内存DC)
        hdc_mem = gdi32.CreateCompatibleDC(hdc_screen)
        if not hdc_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建字体
        hfont = gdi32.CreateFontW(
            size, 0, 0, 0, 400,  # 高度、宽度、角度、方向、粗细
            0, 0, 0, 1, 4,  # 斜体、下划线、删除线、字符集、输出精度
            0, 0, 0, font_name  # 剪辑精度、质量、间距、字体
        )
        if not hfont:
            raise ctypes.WinError(ctypes.get_last_error())

        try:
            # 选入字体
            hfont_old = gdi32.SelectObject(hdc_mem, hfont)
            if not hfont_old:
                raise ctypes.WinError(ctypes.get_last_error())

            # 获取文本尺寸
            text_size = ctypes.wintypes.SIZE()
            if not gdi32.GetTextExtentPoint32W(hdc_mem, text, len(text), ctypes.byref(text_size)):
                raise ctypes.WinError(ctypes.get_last_error())

            # 创建兼容位图
            w, h = text_size.cx + 20, text_size.cy + 20  # 增加一些边距
            hbm_mem = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
            if not hbm_mem:
                raise ctypes.WinError(ctypes.get_last_error())

            # 将位图选入内存DC
            hbm_old = gdi32.SelectObject(hdc_mem, hbm_mem)
            if not hbm_old:
                raise ctypes.WinError(ctypes.get_last_error())

            try:
                # 关键步骤：将内存DC中的文字背景设置为透明
                prev_mode = gdi32.SetBkMode(hdc_mem, TRANSPARENT)
                if prev_mode == 0:
                    raise ctypes.WinError(ctypes.get_last_error())

                # 设置文字颜色
                gdi32.SetTextColor(hdc_mem, color)

                # 在内存DC上绘制文字（背景已设置为透明）
                if not gdi32.TextOutW(hdc_mem, 10, 10, text, len(text)):
                    raise ctypes.WinError(ctypes.get_last_error())

                # 将内存DC内容复制到屏幕
                if not gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY):
                    raise ctypes.WinError(ctypes.get_last_error())

                print(f"已绘制透明背景的文字: {text}")
                return (x, y, w, h)  # 返回绘制区域的坐标和尺寸


            finally:
                # 恢复原背景模式
                gdi32.SetBkMode(hdc_mem, prev_mode)
                # 清理资源
                gdi32.SelectObject(hdc_mem, hbm_old)
                gdi32.DeleteObject(hbm_mem)


        finally:
            # 恢复原字体
            gdi32.SelectObject(hdc_mem, hfont_old)
            gdi32.DeleteObject(hfont)

        # 释放桌面DC
        user32.ReleaseDC(HWND_DESKTOP, hdc_screen)


    except Exception as e:
        print(f"绘制错误: {str(e)}")
    return None


def clear_desktop_area(x, y, w, h):
    """清除桌面上指定区域的内容"""
    try:
        # 获取桌面设备上下文
        hdc_screen = user32.GetDC(HWND_DESKTOP)
        if not hdc_screen:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建内存设备上下文
        hdc_mem = gdi32.CreateCompatibleDC(hdc_screen)
        if not hdc_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建兼容位图
        hbm_mem = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
        if not hbm_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 将位图选入内存DC
        hbm_old = gdi32.SelectObject(hdc_mem, hbm_mem)
        if not hbm_old:
            raise ctypes.WinError(ctypes.get_last_error())

        try:
            # 将桌面背景复制到内存DC
            if not gdi32.BitBlt(hdc_mem, 0, 0, w, h, hdc_screen, x, y, SRCCOPY):
                raise ctypes.WinError(ctypes.get_last_error())

            # 延迟一下再清除
            time.sleep(3)

            # 将原始背景复制回桌面，清除文字
            if not gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY):
                raise ctypes.WinError(ctypes.get_last_error())

            print(f"已清除区域: x={x}, y={y}, w={w}, h={h}")


        finally:
            # 清理资源
            gdi32.SelectObject(hdc_mem, hbm_old)
            gdi32.DeleteObject(hbm_mem)
            gdi32.DeleteDC(hdc_mem)

        # 释放桌面DC
        user32.ReleaseDC(HWND_DESKTOP, hdc_screen)


    except Exception as e:
        print(f"清除错误: {str(e)}")


def draw_animated_text(text, size=100, x=100, y=100, color=RGB_RED, font_name="SimHei", sleepseconds=0.5):
    """绘制带有淡入淡出动画的文字"""
    try:
        # 获取桌面设备上下文
        hdc_screen = user32.GetDC(HWND_DESKTOP)
        if not hdc_screen:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建内存设备上下文
        hdc_mem = gdi32.CreateCompatibleDC(hdc_screen)
        if not hdc_mem:
            raise ctypes.WinError(ctypes.get_last_error())

        # 创建字体
        hfont = gdi32.CreateFontW(
            size, 0, 0, 0, 400,  # 高度、宽度、角度、方向、粗细
            0, 0, 0, 1, 4,  # 斜体、下划线、删除线、字符集、输出精度
            0, 0, 0, font_name  # 剪辑精度、质量、间距、字体
        )
        if not hfont:
            raise ctypes.WinError(ctypes.get_last_error())

        try:
            # 选入字体
            hfont_old = gdi32.SelectObject(hdc_mem, hfont)
            if not hfont_old:
                raise ctypes.WinError(ctypes.get_last_error())

            # 获取文本尺寸
            text_size = ctypes.wintypes.SIZE()
            if not gdi32.GetTextExtentPoint32W(hdc_mem, text, len(text), ctypes.byref(text_size)):
                raise ctypes.WinError(ctypes.get_last_error())

            # 创建兼容位图
            w, h = text_size.cx + 20, text_size.cy + 20  # 增加一些边距
            hbm_mem = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
            if not hbm_mem:
                raise ctypes.WinError(ctypes.get_last_error())

            # 将位图选入内存DC
            hbm_old = gdi32.SelectObject(hdc_mem, hbm_mem)
            if not hbm_old:
                raise ctypes.WinError(ctypes.get_last_error())

            try:
                # 保存原始背景
                hdc_bg = gdi32.CreateCompatibleDC(hdc_screen)
                hbm_bg = gdi32.CreateCompatibleBitmap(hdc_screen, w, h)
                gdi32.SelectObject(hdc_bg, hbm_bg)
                gdi32.BitBlt(hdc_bg, 0, 0, w, h, hdc_screen, x, y, SRCCOPY)

                # 设置透明背景
                prev_mode = gdi32.SetBkMode(hdc_mem, TRANSPARENT)
                gdi32.SetTextColor(hdc_mem, color)

                # 淡入效果
                for alpha in range(0, 256, 10):
                    # 清除内存DC
                    gdi32.BitBlt(hdc_mem, 0, 0, w, h, hdc_bg, 0, 0, SRCCOPY)

                    # 绘制文字
                    gdi32.TextOutW(hdc_mem, 10, 10, text, len(text))

                    # 复制到屏幕
                    gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY)

                    # 同样可以节约一点时间
                    # time.sleep(0.02)

                # 保持显示3秒
                time.sleep(sleepseconds)

                # 淡出效果
                for alpha in range(255, -1, -10):
                    # 清除内存DC
                    gdi32.BitBlt(hdc_mem, 0, 0, w, h, hdc_bg, 0, 0, SRCCOPY)

                    # 绘制文字
                    gdi32.TextOutW(hdc_mem, 10, 10, text, len(text))

                    # 复制到屏幕
                    gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_mem, 0, 0, SRCCOPY)

                    time.sleep(0.02)

                # 恢复原始背景
                gdi32.BitBlt(hdc_screen, x, y, w, h, hdc_bg, 0, 0, SRCCOPY)

                print(f"已绘制动画文字: {text}")


            finally:
                # 恢复原背景模式
                gdi32.SetBkMode(hdc_mem, prev_mode)
                # 清理资源
                gdi32.SelectObject(hdc_mem, hbm_old)
                gdi32.DeleteObject(hbm_mem)
                gdi32.DeleteDC(hdc_bg)
                gdi32.DeleteObject(hbm_bg)


        finally:
            # 恢复原字体
            gdi32.SelectObject(hdc_mem, hfont_old)
            gdi32.DeleteObject(hfont)

        # 释放桌面DC
        user32.ReleaseDC(HWND_DESKTOP, hdc_screen)


    except Exception as e:
        print(f"动画绘制错误: {str(e)}")


def show_classification_text():
    """主函数：监控时间并在桌面上显示相应文本"""
    # 加载时间-文本配置并转换为秒数
    time_texts = load_time_texts()
    timed_events = {}
    for time_str, text in time_texts.items():
        try:
            minutes, seconds = time_str.split("分:")
            seconds = seconds.replace("秒", "").strip()
            total_seconds = int(minutes) * 60 + int(seconds)
            timed_events[total_seconds] = text
        except Exception as e:
            print(f"JSON格式错误，跳过无效条目 {time_str}：{e}")

    # 获取屏幕尺寸
    screen_width = user32.GetSystemMetrics(0)  # SM_CXSCREEN
    screen_height = user32.GetSystemMetrics(1)  # SM_CYSCREEN
    print(f"屏幕尺寸: {screen_width}x{screen_height}")

    start_time = int(time.time())
    displayed_events = set()
    event_positions = []  # 存储已显示事件的位置和尺寸

    # 颜色列表，循环使用
    colors = [RGB_RED, RGB_YELLOW, RGB_GREEN, RGB_BLUE]
    color_index = 0

    print("计时已开始...")
    print(f"设置的时间点: {timed_events}")

    try:
        while True:
            elapsed = int(time.time()) - start_time

            # 显示经过的时间
            minutes = elapsed // 60
            seconds = elapsed % 60
            print(f"\r已过去: {minutes}分{seconds}秒", end="", flush=True)

            # 检查是否需要显示新事件
            if elapsed in timed_events and elapsed not in displayed_events:
                text = timed_events[elapsed]
                color = colors[color_index % len(colors)]
                color_index += 1

                # 计算显示位置（在屏幕上部分布）
                event_count = len(event_positions)
                x = 900
                y = 200 + event_count * 120  # 每个事件间隔120像素

                # 确保不超出屏幕高度
                if y + 100 > screen_height:
                    y = screen_height - 150

                print(f"\n时间点 {minutes}分{seconds}秒: {text}")

                # 绘制带有动画效果的文字
                draw_animated_text(text, size=80, x=x, y=y, color=color, sleepseconds=2)

                displayed_events.add(elapsed)

            time.sleep(0.1)


    except KeyboardInterrupt:
        print("\n程序正在退出...")

        # 清理所有显示的文字
        for pos in event_positions:
            if pos:
                clear_desktop_area(*pos)

        print("程序已退出")


def is_key_pressed(key_code):
    """检查指定键是否被按下"""
    return (user32.GetKeyState(key_code) & 0x8000) != 0


def check_key_combination(keys):
    """检查指定的组合键是否被按下"""
    if not keys:
        return False

    # 键名到虚拟键码的映射
    key_map = {
        'ctrl': VK_CONTROL,
        'shift': VK_SHIFT,
        'alt': VK_ALT,
        'f1': VK_F1,
        'f2': VK_F2,
        'f3': VK_F3,
        'f4': VK_F4,
        'f5': VK_F5,
        'f6': VK_F6,
        'f7': VK_F7,
        'f8': VK_F8,
        'f9': VK_F9,
        'f10': VK_F10,
        'f11': VK_F11,
        'f12': VK_F12,
        'esc': VK_ESCAPE,
        'enter': VK_RETURN,
        'space': VK_SPACE,
        'tab': VK_TAB,
        'backspace': VK_BACK,
        'delete': VK_DELETE,
        'home': VK_HOME,
        'end': VK_END,
        'pageup': VK_PRIOR,
        'pagedown': VK_NEXT,
        'up': VK_UP,
        'down': VK_DOWN,
        'left': VK_LEFT,
        'right': VK_RIGHT
    }

    # 转换键名到虚拟键码
    key_codes = []
    for key in keys:
        key = key.lower()
        if key in key_map:
            key_codes.append(key_map[key])
        elif len(key) == 1 and key.isalpha():
            # 字母键
            key_codes.append(ord(key.upper()))
        else:
            print(f"不支持的键: {key}")
            return False

    # 检查所有键是否都被按下
    for code in key_codes:
        if not is_key_pressed(code):
            return False

    return True


# 全局变量，用于控制auto_key_sequence线程
auto_key_thread = None
auto_key_running = False


def keyboard_listener():
    """键盘监听线程函数 - 监听全局快捷键"""
    # 加载键盘配置
    input_config = load_keyboard_config()
    global_shortcuts = input_config.get('global_shortcuts', {})

    start_keys = global_shortcuts.get('start_timing', {}).get('keys', ['ctrl', 'f10'])
    exit_keys = global_shortcuts.get('exit_program', {}).get('keys', ['ctrl', 'shift', 'f10'])

    print("键盘监听已启动，等待以下快捷键:")
    print(f"  启动计时: {'+'.join(start_keys)}")
    print(f"  退出程序: {'+'.join(exit_keys)}")
    print(f"  切换种族(上): Ctrl+Up")
    print(f"  切换种族(下): Ctrl+Down")

    timer_started = False
    global auto_key_thread, auto_key_running

    # 种族切换快捷键状态
    prev_race_up_state = False
    prev_race_down_state = False

    while True:
        # 检查启动计时快捷键
        if not timer_started and check_key_combination(start_keys):
            print(f"\n检测到 {'+'.join(start_keys)}，开始计时...")

            # 在桌面画出"逻辑开始"中文字
            draw_animated_text("逻辑开始", size=80, x=500, y=300, color=RGB_GREEN, sleepseconds=0.5)

            # 启动计时线程
            timer_thread = threading.Thread(target=show_classification_text)
            timer_thread.daemon = True
            timer_thread.start()

            timer_started = True
            # 等待按键释放
            time.sleep(0.5)

        # 检查种族切换快捷键 - Ctrl+Up
        current_race_up_state = is_key_pressed(VK_CONTROL) and is_key_pressed(VK_UP)
        if current_race_up_state and not prev_race_up_state:
            print("\n检测到 Ctrl+Up，切换到上一个种族...")
            switch_race("prev")
            # 等待按键释放
            time.sleep(0.5)
        prev_race_up_state = current_race_up_state

        # 检查种族切换快捷键 - Ctrl+Down
        current_race_down_state = is_key_pressed(VK_CONTROL) and is_key_pressed(VK_DOWN)
        if current_race_down_state and not prev_race_down_state:
            print("\n检测到 Ctrl+Down，切换到下一个种族...")
            switch_race("next")
            # 等待按键释放
            time.sleep(0.5)
        prev_race_down_state = current_race_down_state

        # 获取当前种族的配置
        current_race_name = get_current_race()
        start_auto_key_config = get_race_config(current_race_name, "start_auto_key")
        stop_auto_key_config = get_race_config(current_race_name, "stop_auto_key")

        start_auto_key_keys = start_auto_key_config.get('keys', ['ctrl', 'f11'])
        stop_auto_key_keys = stop_auto_key_config.get('keys', ['ctrl', 'shift', 'f11'])

        # 检查启动自动按键快捷键
        if not auto_key_running and check_key_combination(start_auto_key_keys):
            print(f"\n检测到 {'+'.join(start_auto_key_keys)}，启动自动按键序列...")

            # 在桌面画出"自动按键开始"中文字
            draw_animated_text("自动按键开始", size=80, x=500, y=400, color=RGB_BLUE, sleepseconds=0.5)

            # 获取自动按键配置
            auto_key_config = start_auto_key_config.get('auto_key_sequence')
            if auto_key_config and isinstance(auto_key_config, dict):
                duration_minutes = auto_key_config.get('duration_minutes', 5)
                actions = auto_key_config.get('actions', [])
                duration_interval_seconds = auto_key_config.get('duration_interval_seconds', 10)

                if actions and isinstance(actions, list):
                    print(f"启动自动按键线程，持续 {duration_minutes} 分钟")
                    auto_key_running = True
                    auto_key_thread = threading.Thread(
                        target=auto_key_press_sequence,
                        args=(actions, duration_minutes, duration_interval_seconds)
                    )
                    auto_key_thread.daemon = True
                    auto_key_thread.start()

            # 等待按键释放
            time.sleep(0.5)

        # 检查停止自动按键快捷键
        if auto_key_running and check_key_combination(stop_auto_key_keys):
            print(f"\n检测到 {'+'.join(stop_auto_key_keys)}，停止自动按键序列...")

            # 在桌面画出"自动按键停止"中文字
            draw_animated_text("自动按键停止", size=80, x=500, y=400, color=RGB_RED, sleepseconds=0.5)

            # 设置标志位停止线程
            auto_key_running = False

            # 等待按键释放
            time.sleep(0.5)

        # 检查退出程序快捷键
        if check_key_combination(exit_keys):
            print(f"\n检测到 {'+'.join(exit_keys)}，退出程序...")
            # 设置标志位停止所有线程
            auto_key_running = False
            # 退出程序
            os.system('taskkill /f /im %s' % 'python.exe')

        time.sleep(0.1)


def get_virtual_key_code(key_char):
    """将字符或键名转换为虚拟键码"""
    key_map = {
        # 数字键
        '0': 0x30, '1': 0x31, '2': 0x32, '3': 0x33, '4': 0x34,
        '5': 0x35, '6': 0x36, '7': 0x37, '8': 0x38, '9': 0x39,

        # 字母键
        'a': 0x41, 'b': 0x42, 'c': 0x43, 'd': 0x44, 'e': 0x45,
        'f': 0x46, 'g': 0x47, 'h': 0x48, 'i': 0x49, 'j': 0x4A,
        'k': 0x4B, 'l': 0x4C, 'm': 0x4D, 'n': 0x4E, 'o': 0x4F,
        'p': 0x50, 'q': 0x51, 'r': 0x52, 's': 0x53, 't': 0x54,
        'u': 0x55, 'v': 0x56, 'w': 0x57, 'x': 0x58, 'y': 0x59, 'z': 0x5A,

        # 功能键
        'f1': 0x70, 'f2': 0x71, 'f3': 0x72, 'f4': 0x73, 'f5': 0x74,
        'f6': 0x75, 'f7': 0x76, 'f8': 0x77, 'f9': 0x78, 'f10': 0x79,
        'f11': 0x7A, 'f12': 0x7B,

        # 控制键
        'escape': 0x1B, 'esc': 0x1B, 'space': 0x20, 'tab': 0x09,
        'backspace': 0x08, 'enter': 0x0D, 'return': 0x0D, 'delete': 0x2E,

        # 方向键
        'up': 0x26, 'down': 0x28, 'left': 0x25, 'right': 0x27,

        # 导航键
        'home': 0x24, 'end': 0x23, 'pageup': 0x21, 'pgup': 0x21,
        'pagedown': 0x22, 'pgdn': 0x22, 'insert': 0x2D, 'ins': 0x2D,

        # 数字小键盘键
        'numpad0': 0x60, 'numpad1': 0x61, 'numpad2': 0x62, 'numpad3': 0x63,
        'numpad4': 0x64, 'numpad5': 0x65, 'numpad6': 0x66, 'numpad7': 0x67,
        'numpad8': 0x68, 'numpad9': 0x69, 'multiply': 0x6A, 'add': 0x6B,
        'subtract': 0x6D, 'decimal': 0x6E, 'divide': 0x6F
    }
    return key_map.get(key_char.lower(), 0)


def simulate_key_press(key_code):
    """模拟按下并释放一个键"""
    # 按下键
    user32.keybd_event(key_code, 0, 0, 0)
    time.sleep(0.01)  # 短暂延迟
    # 释放键
    user32.keybd_event(key_code, 0, KEYEVENTF_KEYUP, 0)


def simulate_mouse_right_click():
    """模拟鼠标右键点击"""
    # 获取当前鼠标位置
    cursor_pos = ctypes.wintypes.POINT()
    user32.GetCursorPos(ctypes.byref(cursor_pos))

    # 模拟鼠标右键按下
    user32.mouse_event(MOUSEEVENTF_RIGHTDOWN, cursor_pos.x, cursor_pos.y, 0, 0)
    time.sleep(0.01)  # 短暂延迟
    # 模拟鼠标右键释放
    user32.mouse_event(MOUSEEVENTF_RIGHTUP, cursor_pos.x, cursor_pos.y, 0, 0)


def simulate_key_sequence(actions):
    """根据配置模拟一系列键位动作"""
    print(f"开始执行键位序列: {actions}")

    for action in actions:
        key = action.get('key', '')
        times = int(action.get('times', 1))
        interval = int(action.get('interval', 1000))
        after_interval = int(action.get('after_interval', 0))

        # 检查是否是鼠标右键点击
        if key.lower() == 'right_click':
            print(f"执行动作: 鼠标右键点击, 次数:{times}, 间隔:{interval}ms")

            # 执行指定次数的鼠标右键点击
            for i in range(times):
                simulate_mouse_right_click()
                if i < times - 1:  # 最后一次不等待
                    time.sleep(interval / 1000)
        else:
            key_code = get_virtual_key_code(key)
            if key_code == 0:
                print(f"不支持的键: {key}")
                continue

            print(f"执行动作: 键'{key}'({hex(key_code)}), 次数:{times}, 间隔:{interval}ms")

            # 执行指定次数的按键
            for i in range(times):
                simulate_key_press(key_code)
                if i < times - 1:  # 最后一次不等待
                    time.sleep(interval / 1000)

        # 执行完当前动作后的等待时间
        if after_interval > 0:
            print(f"动作后等待 {after_interval}ms")
            time.sleep(after_interval / 1000)

    print("键位序列执行完成")


def auto_key_press_sequence(actions, duration_minutes, duration_interval_seconds):
    # duration_interval_seconds: 在整个时间段内，需要间隔停止的秒数
    """自动按键序列 - 在指定分钟内循环执行按键动作"""
    print(f"自动按键序列开始，持续 {duration_minutes} 分钟")

    end_time = time.time() + duration_minutes * 60
    sequence_index = 0
    global auto_key_running

    while time.time() < end_time and auto_key_running:
        # 循环执行动作序列
        current_action = actions[sequence_index % len(actions)]

        key = current_action.get('key', '')
        times = int(current_action.get('times', 1))
        interval = int(current_action.get('interval', 1000))
        after_interval = int(current_action.get('after_interval', 0))

        print(f"自动执行: {current_action}")

        # 执行当前动作
        if key.lower() == 'right_click':
            for i in range(times):
                if not auto_key_running:  # 检查是否需要停止
                    break
                simulate_mouse_right_click()
                if i < times - 1:
                    time.sleep(interval / 1000)
        else:
            key_code = get_virtual_key_code(key)
            if key_code != 0:
                for i in range(times):
                    if not auto_key_running:  # 检查是否需要停止
                        break
                    simulate_key_press(key_code)
                    if i < times - 1:
                        time.sleep(interval / 1000)

        # 如果配置了after_interval，那么就需要等待，如果没有配置，那么就不需要等待
        if after_interval > 0:
            time.sleep(after_interval / 1000)

        # 切换到下一个动作
        sequence_index += 1

        # 已经完成一轮了所有按键了，那么就需要进行时间上的一轮等待，下轮才可以完整的按完一轮按键
        if sequence_index >= len(actions):
            # 动作后等待，以保证时间之间的间隔
            if duration_interval_seconds > 0:
                time.sleep(duration_interval_seconds)

                # 保证下轮循环，是重新开始的
                sequence_index = 0

        # 检查是否超时或需要停止
        if time.time() >= end_time or not auto_key_running:
            break

    print(f"自动按键序列结束，已持续 {duration_minutes} 分钟")
    auto_key_running = False  # 重置运行状态


def input_event_listener():
    """输入事件监听线程 - 监听键盘和鼠标事件并执行对应的键位序列"""

    print("输入事件监听已启动，等待事件触发...")

    # 鼠标状态变量
    mouse_state = {
        'left_button': False,
        'right_button': False,
        'wheel_delta': 0
    }

    # 鼠标钩子相关变量
    WH_MOUSE_LL = 14
    WM_LBUTTONDOWN = 0x0201
    WM_LBUTTONUP = 0x0202
    WM_RBUTTONDOWN = 0x0204
    WM_RBUTTONUP = 0x0205
    WM_MOUSEWHEEL = 0x020A

    # 定义MOUSEHOOKSTRUCT结构
    class MOUSEHOOKSTRUCT(ctypes.Structure):
        _fields_ = [
            ("pt", ctypes.wintypes.POINT),
            ("hwnd", ctypes.wintypes.HWND),
            ("wHitTestCode", ctypes.c_uint),
            ("dwExtraInfo", ctypes.wintypes.LPARAM)
        ]

    # 定义MSLLHOOKSTRUCT结构（用于低级鼠标钩子）
    class MSLLHOOKSTRUCT(ctypes.Structure):
        _fields_ = [
            ("pt", ctypes.wintypes.POINT),
            ("mouseData", ctypes.c_uint),
            ("flags", ctypes.c_uint),
            ("time", ctypes.c_uint),
            ("dwExtraInfo", ctypes.wintypes.LPARAM)
        ]

    # 鼠标钩子回调函数
    def mouse_hook_proc(nCode, wParam, lParam):
        if nCode >= 0:
            # 左键按下
            if wParam == WM_LBUTTONDOWN:
                mouse_state['left_button'] = True
            # 左键释放
            elif wParam == WM_LBUTTONUP:
                mouse_state['left_button'] = False
            # 右键按下
            elif wParam == WM_RBUTTONDOWN:
                mouse_state['right_button'] = True
            # 右键释放
            elif wParam == WM_RBUTTONUP:
                mouse_state['right_button'] = False
            # 鼠标滚轮
            elif wParam == WM_MOUSEWHEEL:
                # 解析MSLLHOOKSTRUCT结构
                msll_struct = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT)).contents
                # 获取滚轮 delta 值，正为向上，负为向下
                wheel_delta = ctypes.c_int16(msll_struct.mouseData >> 16).value
                mouse_state['wheel_delta'] = wheel_delta

        # 调用下一个钩子
        return user32.CallNextHookEx(None, nCode, wParam, lParam)

    # 设置鼠标钩子
    CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_void_p))
    mouse_hook = CMPFUNC(mouse_hook_proc)
    mouse_hook_handle = user32.SetWindowsHookExW(WH_MOUSE_LL, mouse_hook, None, 0)

    if not mouse_hook_handle:
        print(f"设置鼠标钩子失败: {ctypes.WinError(ctypes.get_last_error())}")
        return

    try:
        while True:
            # 获取当前种族的配置
            current_race_name = get_current_race()
            keyboard_shortcuts = get_race_config(current_race_name, "keyboard_shortcuts")
            mouse_shortcuts = get_race_config(current_race_name, "mouse_shortcuts")

            # 准备键盘快捷键配置
            keyboard_configs = []
            for shortcut in keyboard_shortcuts:
                trigger_key = shortcut.get('trigger_key', '')
                actions = shortcut.get('actions', [])

                if not trigger_key or not isinstance(actions, list):
                    print(f"无效的键盘快捷键配置: {shortcut}")
                    continue

                trigger_key_code = get_virtual_key_code(trigger_key)
                if trigger_key_code == 0:
                    print(f"无效的键盘触发键: {trigger_key}")
                    continue

                keyboard_configs.append({
                    'trigger_type': 'keyboard',
                    'trigger_key': trigger_key,
                    'trigger_key_code': trigger_key_code,
                    'actions': actions,
                    'key_pressed': False  # 用于边缘检测
                })

            # 准备鼠标快捷键配置
            mouse_configs = []
            mouse_trigger_map = {
                'left_click': 'left_click',
                'right_click': 'right_click',
                'wheel_up': 'wheel_up',
                'wheel_down': 'wheel_down'
            }

            for shortcut in mouse_shortcuts:
                trigger_event = shortcut.get('trigger_event', '').lower()
                actions = shortcut.get('actions', [])

                if trigger_event not in mouse_trigger_map or not isinstance(actions, list):
                    print(f"无效的鼠标快捷键配置: {shortcut}")
                    continue

                mouse_configs.append({
                    'trigger_type': 'mouse',
                    'trigger_event': trigger_event,
                    'actions': actions,
                    'event_triggered': False  # 用于边缘检测
                })

            # 检查键盘事件
            for config in keyboard_configs:
                # 检查触发键状态
                current_state = (user32.GetKeyState(config['trigger_key_code']) & 0x8000) != 0

                # 检测按键按下事件（边缘检测）
                if current_state and not config['key_pressed']:
                    config['key_pressed'] = True
                    print(f"\n检测到键盘 '{config['trigger_key']}' 键按下，执行键位序列...")

                    # 启动键位模拟线程
                    key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                    key_thread.daemon = True
                    key_thread.start()


                # 检测按键释放事件
                elif not current_state and config['key_pressed']:
                    config['key_pressed'] = False

            # 检查鼠标事件
            # 左键点击
            if mouse_state['left_button']:
                for config in mouse_configs:
                    if config['trigger_event'] == 'left_click' and not config['event_triggered']:
                        config['event_triggered'] = True
                        print(f"\n检测到鼠标左键点击，执行键位序列...")

                        # 启动键位模拟线程
                        key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                        key_thread.daemon = True
                        key_thread.start()
            else:
                # 重置左键点击状态
                for config in mouse_configs:
                    if config['trigger_event'] == 'left_click':
                        config['event_triggered'] = False

            # 右键点击
            if mouse_state['right_button']:
                for config in mouse_configs:
                    if config['trigger_event'] == 'right_click' and not config['event_triggered']:
                        config['event_triggered'] = True
                        print(f"\n检测到鼠标右键点击，执行键位序列...")

                        # 启动键位模拟线程
                        key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                        key_thread.daemon = True
                        key_thread.start()
            else:
                # 重置右键点击状态
                for config in mouse_configs:
                    if config['trigger_event'] == 'right_click':
                        config['event_triggered'] = False

            # 鼠标滚轮
            if mouse_state['wheel_delta'] != 0:
                if mouse_state['wheel_delta'] > 0:  # 滚轮向上
                    for config in mouse_configs:
                        if config['trigger_event'] == 'wheel_up' and not config['event_triggered']:
                            config['event_triggered'] = True
                            print(f"\n检测到鼠标滚轮向上，执行键位序列...")

                            # 启动键位模拟线程
                            key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                            key_thread.daemon = True
                            key_thread.start()
                else:  # 滚轮向下
                    for config in mouse_configs:
                        if config['trigger_event'] == 'wheel_down' and not config['event_triggered']:
                            config['event_triggered'] = True
                            print(f"\n检测到鼠标滚轮向下，执行键位序列...")

                            # 启动键位模拟线程
                            key_thread = threading.Thread(target=simulate_key_sequence, args=(config['actions'],))
                            key_thread.daemon = True
                            key_thread.start()

                # 重置滚轮状态
                mouse_state['wheel_delta'] = 0
                # 短暂延迟避免重复触发
                time.sleep(0.1)

            # 处理Windows消息
            msg = ctypes.wintypes.MSG()
            user32.PeekMessageW(ctypes.byref(msg), None, 0, 0, 1)

            time.sleep(0.01)


    except KeyboardInterrupt:
        print("\n输入事件监听已停止")


    finally:
        # 移除鼠标钩子
        user32.UnhookWindowsHookEx(mouse_hook_handle)


if __name__ == "__main__":
    try:
        # 程序启动时自动切换到英文输入法
        switch_to_english_input()

        # 显示当前选中的种族
        print(f"当前选中种族: {current_race}")

        # 启动键盘监听线程（Ctrl+F10开始计时）
        listener_thread = threading.Thread(target=keyboard_listener)
        listener_thread.daemon = True
        listener_thread.start()

        # 启动输入事件监听线程（监听键盘和鼠标事件）
        input_thread = threading.Thread(target=input_event_listener)
        input_thread.daemon = True
        input_thread.start()

        # 主线程等待
        while True:
            time.sleep(1)


    except KeyboardInterrupt:
        print("\n程序已退出")
